<template>
  <div class="app-container">
    <!-- 筛选表单 -->
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="老人姓名" prop="elderNameInput">
        <el-input
            v-model="queryParams.elderNameInput"
            placeholder="请输入老人姓名"
            clearable
            @blur="handleElderNameBlur"
            @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="床位号" prop="bedNum">
        <el-input
            v-model="queryParams.bedNum"
            placeholder="请输入床位号"
            clearable
            @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="openRechargeDialog" style="margin-left: 360px;margin-top: 10px;width: 80px">充值</el-button>
      </el-form-item>
    </el-form>

    <!-- 充值列表表格：序号按1-n正序排列 -->
    <el-table v-loading="loading" :data="rechargeList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <!-- 序号列：按当前页+行索引计算正序编号 -->
      <el-table-column label="序号" align="center">
        <template #default="scope">
          {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column label="预缴款编号" align="center" prop="prepaidNo" />
      <el-table-column label="老人姓名" align="center" prop="elderName" />
      <el-table-column label="床位号" align="center" prop="bedNum" />
      <el-table-column label="充值方式" align="center" prop="method" />
      <el-table-column label="充值金额" align="center" prop="amount" />
      <el-table-column label="充值凭证" align="center" prop="voucher">
        <template #default="scope">
          <el-image
              v-if="scope.row.voucher"
              :src="formatImageUrl(scope.row.voucher)"
              style="width: 60px; height: 60px; border: 1px solid #eee; pointer-events: none;"
              fit="cover"
              @error="handleImageError(scope.row)"
          />
          <span v-else>无</span>
        </template>
      </el-table-column>
      <el-table-column label="充值备注" align="center" prop="remark" />
      <el-table-column label="创建人" align="center" prop="createdBy" />
      <el-table-column label="创建时间" align="center" prop="createdAt" width="180">
        <template #default="scope">
          <span>{{ formatTime(scope.row.createdAt) }}</span>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页组件 -->
    <pagination
        v-show="total>0"
        :total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="getList"
    />

    <!-- 上传充值凭证弹窗 -->
    <el-dialog title="上传充值凭证" v-model="rechargeDialogVisible" width="450px" append-to-body>
      <el-form ref="rechargeFormRef" :model="rechargeForm" :rules="rechargeRules" label-width="80px">
        <el-form-item label="老人姓名" prop="name">
          <el-input
              v-model="rechargeForm.name"
              placeholder="请输入老人姓名"
              @blur="handleNameBlur"
              style="width: 100%"
          ></el-input>
        </el-form-item>

        <el-form-item label="床位号" prop="bedNum">
          <el-input
              v-model="rechargeForm.bedNum"
              placeholder="系统自动获取"
              readonly
              style="width: 100%"
          ></el-input>
        </el-form-item>

        <el-form-item label="充值方式" prop="method">
          <el-select
              v-model="rechargeForm.method"
              placeholder="请选择充值方式"
              style="width: 100%"
          >
            <el-option key="1" label="微信" value="微信"/>
            <el-option key="2" label="支付宝" value="支付宝"/>
            <el-option key="3" label="网银" value="网银"/>
            <el-option key="4" label="现金" value="现金"/>
            <el-option key="5" label="其他" value="其他"/>
          </el-select>
        </el-form-item>

        <el-form-item label="充值金额" prop="amount">
          <el-input-number
              v-model="rechargeForm.amount"
              :min="0.01"
              step="0.01"
              placeholder="请输入充值金额"
              style="width: 50%;"
              :style="{
              border: '1px solid #dcdfe6',
              borderRadius: '4px',
              '--el-input-number-input-height': '32px'
            }"
          ></el-input-number>
        </el-form-item>

        <el-form-item label="充值凭证" prop="voucher">
          <el-upload
              class="upload-demo"
              action="http://localhost:8080/common/upload"
              :headers="headers"
              :on-success="handleUploadSuccess"
              :before-upload="beforeUpload"
              :file-list="fileList"
              :limit="1"
              accept=".png,.jpg,.jpeg"
              :on-error="handleUploadError"
              :on-remove="handleFileRemove"
              list-type="picture"
              style="margin-bottom: 16px;"
          >
            <el-button type="primary" style="width: 200px;height: 50px;background-color: #F5F5F5;color: #C8C9C8">
              <el-icon style="margin-right: 8px;"><UploadIcon /></el-icon>
              点击上传图片
            </el-button>
            <div slot="tip" class="el-upload__tip" style="margin-left: 10px;white-space:wrap">
              图片大小不超过2MB，仅支持PNG、JPG、JPEG类型
            </div>
          </el-upload>
        </el-form-item>

        <el-form-item label="充值备注" prop="remark">
          <el-input
              v-model="rechargeForm.remark"
              type="textarea"
              :maxlength="50"
              show-word-limit
              placeholder="请输入充值备注（如：2024年10月护理费）"
              style="width: 100%"
          ></el-input>
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="rechargeDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitRecharge">确定上传</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="Recharge">
import { listRecharge } from "@/api/recharge/recharge"
import { addBalance } from "@/api/balance/balance"  // 导入新增余额接口
import { reactive, ref, computed, onMounted, getCurrentInstance } from 'vue'
import { ElMessage, ElIcon } from 'element-plus'
import { Upload as UploadIcon } from '@element-plus/icons-vue'
import { getToken } from '@/utils/auth'
import Pagination from '@/components/Pagination/index.vue'
import { toRefs } from 'vue'

// 调试函数：增强日志详细度
const logDebug = (message, data = null, type = 'info') => {
  const timestamp = new Date().toISOString()
  console[type](`[充值组件调试][${timestamp}] ${message}`, data || '')
}

// 基础配置
const { proxy } = getCurrentInstance()
const BASE_API = 'http://localhost:8080'  // 后端基础地址，需与实际一致

// 列表相关响应式数据
const rechargeList = ref([])
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const total = ref(0)

// 弹窗表单数据
const rechargeDialogVisible = ref(false)
const rechargeForm = ref({
  name: '',
  elderId: '',
  bedNum: '',
  method: '',
  amount: 0,
  voucher: '',
  remark: ''
})
const fileList = ref([])
const rechargeFormRef = ref(null)

// 上传请求头（携带Token）
const headers = ref({
  Authorization: 'Bearer ' + getToken()
})

// 表单验证规则
const rechargeRules = {
  name: [{ required: true, message: '请输入老人姓名', trigger: 'blur' }],
  elderId: [{ required: true, message: '老人信息验证失败', trigger: 'change' }],
  bedNum: [{ required: true, message: '无法获取床位信息', trigger: 'change' }],
  method: [{ required: true, message: '请选择充值方式', trigger: 'change' }],
  amount: [
    { required: true, message: '请输入充值金额', trigger: 'blur' },
    { type: 'number', min: 0.01, message: '充值金额不能小于0.01元', trigger: 'blur' }
  ],
  voucher: [{ required: true, message: '请上传充值凭证图片', trigger: 'change' }],
  remark: [{ required: true, message: '请输入充值备注', trigger: 'blur' }]
}

// 去重老人列表（用于内部逻辑）
const uniqueElderList = computed(() => {
  const elderMap = new Map()
  rechargeList.value.forEach(item => {
    if (item.elderName && item.elderId) elderMap.set(item.elderName, item.elderId)
  })
  return Array.from(elderMap).map(([elderName, elderId]) => ({ elderName, elderId }))
})

// 查询参数：输入姓名临时存储+实际搜索参数（ID/床位号）
const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    elderNameInput: null,  // 输入的老人姓名（临时）
    elderId: null,         // 实际搜索的老人ID
    bedNum: null           // 实际搜索的床位号
  }
})
const { queryParams } = toRefs(data)

// 时间格式化工具（支持标准时间格式）
const formatTime = (time) => {
  if (!time) return ''
  const date = new Date(time)
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`
}

// 图片地址格式化：确保带后端基础地址前缀
const formatImageUrl = (url) => {
  if (!url) return ''
  return url.startsWith('http') ? url : `${BASE_API}${url}`
}

// 图片加载错误处理
const handleImageError = (row) => {
  ElMessage.warning(`老人【${row.elderName}】的凭证图片加载失败，请检查地址：${row.voucher}`)
  row.voucher = ''
}

// 列表加载方法：携带正确搜索参数+格式化图片地址
function getList() {
  const searchParams = {
    pageNum: queryParams.value.pageNum,
    pageSize: queryParams.value.pageSize,
    elderId: queryParams.value.elderId,
    bedNum: queryParams.value.bedNum
  }
  logDebug('开始加载充值列表（搜索参数）', searchParams)
  loading.value = true
  listRecharge(searchParams).then(response => {
    logDebug('充值列表加载成功', { total: response.total, rows: response.rows.length })
    // 格式化所有图片地址
    const formattedList = response.rows.map(item => ({
      ...item,
      voucher: formatImageUrl(item.voucher)
    }))
    rechargeList.value = formattedList
    total.value = response.total
  }).catch(err => {
    logDebug('充值列表加载失败', err, 'error')
    ElMessage.error('获取充值列表失败，请刷新页面重试')
  }).finally(() => {
    loading.value = false
  })
}

// 搜索功能：触发列表加载+重置页码
function handleQuery() {
  logDebug('触发搜索操作', {
    trigger: '按钮点击/回车',
    inputName: queryParams.value.elderNameInput,
    elderId: queryParams.value.elderId,
    bedNum: queryParams.value.bedNum
  })
  queryParams.value.pageNum = 1
  getList()
}

// 重置功能：清空所有搜索条件+重置页码
function resetQuery() {
  logDebug('触发重置操作（重置前参数）', { ...queryParams.value })
  if (proxy?.$refs.queryRef) {
    proxy.$refs.queryRef.resetFields()
  }
  queryParams.value.elderNameInput = null
  queryParams.value.elderId = null
  queryParams.value.bedNum = null
  queryParams.value.pageNum = 1
  logDebug('触发重置操作（重置后参数）', { ...queryParams.value })
  handleQuery()
}

// 表格选择事件
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.id)
  logDebug('表格选中记录ID', ids.value)
}

// 打开充值弹窗
function openRechargeDialog() {
  logDebug('打开充值弹窗')
  rechargeForm.value = {
    name: '',
    elderId: '',
    bedNum: '',
    method: '',
    amount: 0,
    voucher: '',
    remark: ''
  }
  fileList.value = []
  if (rechargeFormRef.value) rechargeFormRef.value.resetFields()
  rechargeDialogVisible.value = true
}

// 搜索框老人姓名失焦：查询ID并赋值
async function handleElderNameBlur() {
  const inputName = queryParams.value.elderNameInput?.trim()
  logDebug('搜索框姓名失焦，查询老人ID', { inputName })

  if (!inputName) {
    queryParams.value.elderId = null
    logDebug('未输入姓名，清空搜索ID')
    return
  }

  try {
    const response = await fetch(
        `${BASE_API}/visit/visit/elderId?name=${encodeURIComponent(inputName)}`,
        {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${getToken()}`,
            'Content-Type': 'application/json'
          }
        }
    )

    if (!response.ok) {
      throw new Error(`查询ID接口失败：${response.statusText}`)
    }
    const result = await response.json()
    logDebug('搜索框ID查询响应', result)

    if (result.code === 200 && result.data?.id) {
      queryParams.value.elderId = result.data.id
      logDebug('搜索框ID查询成功', { inputName, elderId: queryParams.value.elderId })
    } else {
      queryParams.value.elderId = null
      ElMessage.warning(`未查询到【${inputName}】的老人信息`)
      logDebug('未查询到老人，清空搜索ID')
    }
  } catch (err) {
    queryParams.value.elderId = null
    logDebug('搜索框ID查询出错', err, 'error')
    ElMessage.error(`查询失败：${err.message || '网络异常'}`)
  }
}

// 充值弹窗姓名失焦：查询ID+床位号
async function handleNameBlur() {
  const name = rechargeForm.value.name.trim()
  logDebug('充值弹窗姓名失焦，开始查询老人信息', { inputName: name })

  if (!name) {
    rechargeForm.value.elderId = ''
    rechargeForm.value.bedNum = ''
    logDebug('未输入姓名，清空老人ID和床位号')
    return
  }

  try {
    // 查询老人ID
    const elderIdResponse = await fetch(
        `${BASE_API}/visit/visit/elderId?name=${encodeURIComponent(name)}`,
        {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${getToken()}`,
            'Content-Type': 'application/json'
          }
        }
    )

    if (!elderIdResponse.ok) {
      throw new Error(`查询ID接口失败：${elderIdResponse.statusText}（状态码：${elderIdResponse.status}）`)
    }
    const elderIdData = await elderIdResponse.json()
    logDebug('弹窗ID查询响应详情', {
      status: elderIdResponse.status,
      code: elderIdData.code,
      data: elderIdData.data
    })

    if (elderIdData.code === 200 && elderIdData.data?.id) {
      const actualElderId = elderIdData.data.id
      rechargeForm.value.elderId = actualElderId
      logDebug('老人ID查询成功', { inputName: name, elderId: actualElderId })
      ElMessage.success('老人信息验证成功')

      // 查询床位号
      const bedNoResponse = await fetch(
          `${BASE_API}/recharge/recharge/bedNo/${actualElderId}`,
          {
            method: 'GET',
            headers: {
              'Authorization': `Bearer ${getToken()}`,
              'Content-Type': 'application/json'
            }
          }
      )

      if (!bedNoResponse.ok) {
        throw new Error(`查询床位接口失败：${bedNoResponse.statusText}（状态码：${bedNoResponse.status}）`)
      }
      const bedNoData = await bedNoResponse.json()
      logDebug('弹窗床位查询响应详情', {
        status: bedNoResponse.status,
        code: bedNoData.code,
        msg: bedNoData.msg
      })

      if (bedNoData.code === 200 && bedNoData.msg) {
        rechargeForm.value.bedNum = bedNoData.msg
        logDebug('床位号查询成功', { elderId: actualElderId, bedNum: bedNoData.msg })
      } else {
        ElMessage.warning('未查询到该老人的床位信息')
        logDebug('床位号查询失败', { reason: bedNoData.msg || '接口返回无数据' })
        rechargeForm.value.bedNum = ''
      }
    } else {
      ElMessage.warning('未查询到该老人信息，请核对姓名')
      logDebug('老人ID查询失败', { reason: elderIdData.msg || '接口返回无数据' })
      rechargeForm.value.elderId = ''
      rechargeForm.value.bedNum = ''
    }

  } catch (err) {
    logDebug('弹窗老人信息处理出错', { message: err.message, stack: err.stack }, 'error')
    ElMessage.error(`处理失败：${err.message || '网络异常'}`)
    rechargeForm.value.elderId = ''
    rechargeForm.value.bedNum = ''
  }
}

// 上传前置校验
function beforeUpload(file) {
  logDebug('准备上传文件', {
    fileName: file.name,
    size: `${(file.size / 1024).toFixed(2)}KB`,
    type: file.type,
    lastModified: new Date(file.lastModified).toISOString()
  })
  const isImage = file.type.startsWith('image/')
  if (!isImage) {
    ElMessage.error('请上传图片文件（PNG/JPG/JPEG）')
    return false
  }
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过2MB')
    return false
  }
  return true
}

// 上传失败处理
function handleUploadError(err) {
  logDebug('文件上传错误', {
    error: err,
    status: err.status,
    statusText: err.statusText,
    response: err.response?.data
  }, 'error')
  const errMsg = err.status === 401
      ? '登录已过期，请重新登录'
      : err.status === 404
          ? '上传接口不存在'
          : '图片上传失败'
  ElMessage.error(errMsg)
}

// 上传成功处理：格式化图片地址
function handleUploadSuccess(response, uploadFile) {
  logDebug('文件上传成功', {
    response: response,
    fileName: uploadFile.name,
    uploadedUrl: response.url
  })
  if (response.code === 200 && response.url) {
    const fullUrl = formatImageUrl(response.url)
    rechargeForm.value.voucher = fullUrl
    fileList.value = [{ uid: uploadFile.uid, name: uploadFile.name, url: fullUrl, status: 'success' }]
    ElMessage.success('图片上传成功')
  } else {
    logDebug('文件上传成功但返回异常', { responseCode: response.code, responseMsg: response.msg }, 'warn')
    ElMessage.error('获取图片地址失败，请重新上传')
  }
}

// 移除已上传文件
function handleFileRemove(file, remainingList) {
  logDebug('移除上传文件', {
    removedFile: file.name,
    remainingCount: remainingList.length,
    remainingFiles: remainingList.map(f => f.name)
  })
  rechargeForm.value.voucher = ''
  fileList.value = remainingList
  if (rechargeFormRef.value) rechargeFormRef.value.clearValidate('voucher')
}

// 提交充值记录（增强余额添加的调试信息）
async function submitRecharge() {
  logDebug('===== 开始执行提交充值流程 =====', { formData: { ...rechargeForm.value } })
  rechargeFormRef.value.validate(async (valid) => {
    if (!valid) {
      logDebug('表单验证失败', { reason: '存在未填写或错误的字段' }, 'warn')
      return
    }

    try {
      // 1. 提交充值记录
      const rechargeData = {
        amount: rechargeForm.value.amount,
        voucher: rechargeForm.value.voucher,
        method: rechargeForm.value.method,
        elderId: rechargeForm.value.elderId,
        bedNum: rechargeForm.value.bedNum,
        remark: rechargeForm.value.remark
      }
      logDebug('1. 准备提交充值数据', {
        url: `${BASE_API}/recharge/recharge`,
        data: rechargeData
      })

      const rechargeResponse = await fetch(
          `${BASE_API}/recharge/recharge`,
          {
            method: 'POST',
            headers: {
              'Authorization': `Bearer ${getToken()}`,
              'Content-Type': 'application/json'
            },
            body: JSON.stringify(rechargeData)
          }
      )

      // 打印充值接口响应状态
      logDebug('1. 充值接口响应状态', {
        status: rechargeResponse.status,
        statusText: rechargeResponse.statusText,
        ok: rechargeResponse.ok
      })

      if (!rechargeResponse.ok) {
        const errorBody = await rechargeResponse.text().catch(() => '无法解析响应体')
        throw new Error(`充值接口请求失败：${rechargeResponse.statusText}（状态码：${rechargeResponse.status}，响应体：${errorBody}）`)
      }

      const rechargeResult = await rechargeResponse.json()
      logDebug('1. 充值接口返回数据', {
        code: rechargeResult.code,
        msg: rechargeResult.msg,
        data: rechargeResult.data
      })

      if (rechargeResult.code !== 200) {
        throw new Error(`充值操作失败：${rechargeResult.msg || '接口返回未知错误'}`)
      }
      logDebug('1. 充值记录添加成功', { rechargeId: rechargeResult.data?.id })

      // 2. 准备调用addBalance接口同步余额
      const currentTime = new Date().toISOString()
      const balanceData = {
        prepaidBalance: rechargeForm.value.amount,  // 充值金额同步到预交款余额
        depositAmount: rechargeForm.value.amount,   // 充值金额同步到押金金额
        elderId: rechargeForm.value.elderId,        // 老人ID
        bedNo: rechargeForm.value.bedNum,           // 床位号
        updatedAt: currentTime                      // 当前时间（ISO格式）
      }
      logDebug('2. 准备调用addBalance接口', {
        url: '/balance/balance',
        data: balanceData,
        timestamp: currentTime
      })

      // 调用余额添加接口并打印详细日志
      const balanceResponse = await addBalance(balanceData)
      logDebug('2. addBalance接口返回完整响应', {
        code: balanceResponse.code,
        msg: balanceResponse.msg,
        data: balanceResponse.data,
        timestamp: new Date().toISOString()
      })

      // 检查余额添加结果
      if (balanceResponse.code !== 200) {
        throw new Error(`余额记录添加失败：${balanceResponse.msg || '接口返回未知错误'}`)
      }
      logDebug('2. 余额记录添加成功', { balanceId: balanceResponse.data?.id })

      // 3. 所有操作成功
      ElMessage.success('充值记录添加成功，余额已同步更新！')
      rechargeDialogVisible.value = false
      fileList.value = []
      getList()  // 刷新充值列表
      logDebug('===== 提交充值流程全部完成 =====')

    } catch (err) {
      logDebug('提交流程执行出错', {
        message: err.message,
        stack: err.stack,
        stage: err.message.includes('充值接口') ? '充值阶段' : '余额添加阶段'
      }, 'error')
      ElMessage.error(`操作失败：${err.message || '网络异常'}`)
    }
  })
}

// 组件初始化：加载初始列表
onMounted(() => {
  logDebug('组件初始化完成，开始加载初始充值列表')
  getList()
})
</script>